package com.chinamsp.dydb.dbsource;

import java.util.Stack;

public class DynamicDataSourceContextHolder {

	private static final ThreadLocal<Stack<DynamicDataSourceGene>> CONTEXT_HOLDER = new ThreadLocal<Stack<DynamicDataSourceGene>>() {

		@Override
		protected Stack<DynamicDataSourceGene> initialValue() {
			return new Stack<DynamicDataSourceGene>();
		}

	};

	private static DataSourceManager dataSourceManager;

	public static void push(String moduleName, DynamicDataSourcePolicyType policy, boolean isWriter) {
		CONTEXT_HOLDER.get().push(new DynamicDataSourceGene(moduleName, policy, isWriter));
	}

	public static DataSourceImpl getDataSource() {
		String moduleName;
		DynamicDataSourceGene dynamicDataSourceGene;
		if (CONTEXT_HOLDER.get() == null || CONTEXT_HOLDER.get().size() == 0) {
			moduleName = dataSourceManager.getDefaultSourceName();
			dynamicDataSourceGene = new DynamicDataSourceGene(moduleName, DynamicDataSourcePolicyType.RANDOM, true);
		}else {
			dynamicDataSourceGene = CONTEXT_HOLDER.get().peek();
			// 获取 数据源
			moduleName = filterModuleName(dynamicDataSourceGene.getModuleName());
		}
		DataSourceImpl master = dataSourceManager.getMasters().get(moduleName);
		if (dynamicDataSourceGene.isMaster()) {
			return master;
		}

		DynamicDataSourcePolicyType slavePolicy = dynamicDataSourceGene.getPolicy();
		return slavePolicy.policy().choose(master, dataSourceManager.getSlaves().get(moduleName), moduleName);
	}

	/**
	 * 检查 注解的模块是否存在，如果不存在，则使用默认的数据源
	 * 
	 * @param moduleName
	 * @return
	 */
	private static String filterModuleName(String moduleName) {
		// 检查有没有这个 module，如果没有就返回默认的数据源
		if (dataSourceManager.getMasters().get(moduleName) == null) {
			moduleName = dataSourceManager.getDefaultSourceName();
		}
		return moduleName;
	}

	public static void pop() {
		CONTEXT_HOLDER.get().pop();
	}

	public static DataSourceManager getDataSourceManager() {
		return dataSourceManager;
	}

	public static void setDataSourceManager(DataSourceManager dataSourceManager) {
		DynamicDataSourceContextHolder.dataSourceManager = dataSourceManager;
	}

}
